﻿using Orleans;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace IOP.Orleans.MessageHub
{
    /// <summary>
    /// 消息调度者接口
    /// </summary>
    public interface IMessageDispatcher<TMessage> : IMessageDispatcher
        where TMessage: class
    {
        /// <summary>
        /// 监听者
        /// </summary>
        IMessageObserver<TMessage> Observer { get; }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message"></param>
        /// <param name="targetObserver"></param>
        Task SendMessage(TMessage message, IMessageObserver<TMessage>[] targetObserver = null);
        /// <summary>
        /// 发送健康检查
        /// </summary>
        /// <param name="data"></param>
        /// <param name="targetObserver"></param>
        Task SendHealthCheck(byte[] data);
        /// <summary>
        /// 注册消息处理函数
        /// </summary>
        /// <param name="handle"></param>
        Task RegistMessageHandle(Func<TMessage, Task> handle);
    }

    /// <summary>
    /// 消息调度者接口
    /// </summary>
    public interface IMessageDispatcher
    {
        /// <summary>
        /// 名称
        /// </summary>
        string Name { get; }
        /// <summary>
        /// 消息发送者
        /// </summary>
        IGrainFactory Client { get; }
        /// <summary>
        /// 是否监听
        /// </summary>
        bool IsListened { get; }
        /// <summary>
        /// 事件，当监听者开始监听时
        /// </summary>
        event Func<IMessageDispatcher, Task> OnObserverBeginListened;
        /// <summary>
        /// 事件，当监听者因为意外停止监听时
        /// </summary>
        event Func<IMessageDispatcher, Task> OnObserverAbortListened;
        /// <summary>
        /// 是否存活
        /// </summary>
        /// <returns></returns>
        bool ImAlive();
        /// <summary>
        /// 健康检查
        /// </summary>
        /// <param name="period"></param>
        void HealthCheck(int period = 30000);
        /// <summary>
        /// 停止健康检查
        /// </summary>
        void StopHealthCheck();
        /// <summary>
        /// 注册健康检查处理函数
        /// </summary>
        /// <param name="handle"></param>
        void RegistHealthCheckHandle(Func<byte[], Task> handle);
    }
}
